﻿Imports System.ComponentModel
Imports MapWinGIS
Imports System.Drawing.Design
Imports System.Windows.Forms.Design
Imports System.Windows.Forms
Imports System.ComponentModel.Design

Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.IO




<Serializable()> Public Class ContourLine
    Inherits SerializableObject


    Public Sub New()
        MyBase.New()

        v = 0.0
        clr = Drawing.Color.White
        LineClr = Drawing.Color.Black



        bShowPoly = True




    End Sub

    '这些都是为了讨厌的VB事件逻辑啊
    Protected Sub New( _
      ByVal info As System.Runtime.Serialization.SerializationInfo, _
      ByVal context As System.Runtime.Serialization.StreamingContext)

        MyBase.New(info, context)

    End Sub





    Dim v As Double
    <CategoryAttribute("基本信息"), _
    NotifyParentProperty(True), _
    Browsable(False), _
DisplayName("等值线值")> _
Public Property VProperty() As Double
        Get
            Return v
        End Get
        Set(ByVal value As Double)
            v = value
        End Set
    End Property


    Dim clr As Drawing.Color
    <CategoryAttribute("基本信息"), _
    NotifyParentProperty(True), _
  DisplayName("等值线内填充色")> _
   Public Property ClrProperty() As Drawing.Color
        Get
            Return clr
        End Get
        Set(ByVal value As Drawing.Color)
            clr = value
        End Set
    End Property

    Dim LineClr As Drawing.Color
    <CategoryAttribute("基本信息"), _
    NotifyParentProperty(True), _
  DisplayName("等值线颜色")> _
    Public Property LnColorProperty() As Drawing.Color
        Get
            Return LineClr
        End Get
        Set(ByVal value As Drawing.Color)
            LineClr = value
        End Set
    End Property

    Dim bShowPoly As Boolean
    <CategoryAttribute("基本信息"), _
    NotifyParentProperty(True), _
DisplayName("是否显示")> _
  Public Property BShowPolyProperty() As Boolean
        Get
            Return bShowPoly
        End Get
        Set(ByVal value As Boolean)
            bShowPoly = value
        End Set
    End Property


End Class

Public Class ContourEditor
    Inherits UITypeEditor

    Private m_cvlist As List(Of ContourLine)
    Private m_SdsContour As SDSContourLayer

    Public Overloads Overrides Function EditValue(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal provider As System.IServiceProvider, ByVal value As Object) As Object
        Dim DialogProvider As IWindowsFormsEditorService ' This object will start the dialog form
        DialogProvider = CType(provider.GetService(GetType(IWindowsFormsEditorService)), Windows.Forms.Design.IWindowsFormsEditorService)
        Dim MyDialog As New CTEditorFormV2(DialogProvider, m_SdsContour)


        If DialogProvider.ShowDialog(MyDialog) = DialogResult.OK Then
            Return MyDialog.cMList
        Else
            Return m_cvlist
        End If
    End Function

    Public Overloads Overrides Function GetEditStyle(ByVal Context As System.ComponentModel.ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
        If TypeOf Context.Instance Is SDSContourLayer Then
            m_SdsContour = CType(Context.Instance, SDSContourLayer)
            m_cvlist = CType(Context.Instance, SDSContourLayer).CListProperty

        Else
            Return UITypeEditorEditStyle.None
        End If
        Return UITypeEditorEditStyle.Modal
    End Function


End Class





<Serializable()> Public Class SDSContourLayer
    Inherits SelfDrawShapeLayer



    Public Sub New(ByVal ln As String)
        MyBase.new(ln)

        ''这里有一个临时使用的代码
        'If System.IO.File.Exists("c:\test\ContourLine.SSS") Then

        '    MyContours = MyContours.Open("c:\test\ContourLine.SSS")


        '    'bContourReady = True

        'End If


        '提供集合的初始化，以及默认值


        GradientClrPolygon = New List(Of Drawing.Color)
        '等值线渐变色
        GradientClrPolygon.Add(Drawing.Color.FromArgb(56, 168, 0))
        GradientClrPolygon.Add(Drawing.Color.FromArgb(255, 255, 0))
        GradientClrPolygon.Add(Drawing.Color.FromArgb(255, 0, 0))
        GradientClrPolygon.Add(Drawing.Color.FromArgb(153, 0, 204))


        GradientClrLine = New List(Of Drawing.Color)
        GradientClrLine.Add(Drawing.Color.Black)

        cList = New List(Of ContourLine)
        Dim conl As ContourLine

        conl = New ContourLine()
        conl.VProperty = 0.001
        conl.ClrProperty = Drawing.Color.Yellow
        cList.Add(conl)

        conl = New ContourLine()
        conl.VProperty = 0.002
        conl.ClrProperty = Drawing.Color.FromArgb(255, 128, 0)
        cList.Add(conl)

        conl = New ContourLine()
        conl.VProperty = 0.003
        conl.ClrProperty = Drawing.Color.FromArgb(255, 128, 128)
        cList.Add(conl)

        conl = New ContourLine()
        conl.VProperty = 0.004
        conl.ClrProperty = Drawing.Color.Red
        cList.Add(conl)



        m_LBPointXA = 0
        m_LBPointYA = 0


        m_bLengendFormat = False
        m_LengendNumPts = 3


        lineWidth = 1

        '下面的兄弟也是临时工，靠，临时工都干不成了，空引用
        ' m_DrawHandle = mapwin.NewDrawing(MapWinGIS.tkDrawReferenceList.dlSpatiallyReferencedList)

    End Sub

    '这些都是为了讨厌的VB事件逻辑啊
    Protected Sub New( _
      ByVal info As System.Runtime.Serialization.SerializationInfo, _
      ByVal context As System.Runtime.Serialization.StreamingContext)

        MyBase.New(info, context)

    End Sub

    '内部重要的字段
    Public MyContours As New DrawContour.Contours
    Dim bContourReady As Boolean = False


    '变化比例
    Dim xScale As Double = 1


    Public Sub SetNewContours(ByVal mc As DrawContour.Contours)

        MyContours = mc

    End Sub


    Dim GradientClrPolygon As List(Of Drawing.Color)
    <CategoryAttribute("颜色渐变集合"), _
    Browsable(False), _
DisplayName("填充渐变色集合")> _
    Public Property PolyGradientListProperty() As List(Of Drawing.Color)
        Get
            Return GradientClrPolygon
        End Get
        Set(ByVal value As List(Of Drawing.Color))

            GradientClrPolygon = value

            ' OnReBuildCLines()
        End Set
    End Property

    Dim GradientClrLine As List(Of Drawing.Color)
    <CategoryAttribute("颜色渐变集合"), _
    Browsable(False), _
DisplayName("线条渐变色集合")> _
  Public Property LineGradientListProperty() As List(Of Drawing.Color)
        Get
            Return GradientClrLine
        End Get
        Set(ByVal value As List(Of Drawing.Color))
            GradientClrLine = value


        End Set
    End Property


    <CategoryAttribute("颜色渐变集合"), _
DisplayName("线条渐变色集合")> _
   Public Property GcrlLineArrayProperty() As Drawing.Color()
        Get
            Return GradientClrLine.ToArray()
        End Get
        Set(ByVal value As Drawing.Color())
            If value.Length > 0 Then
                GradientClrLine.Clear()
                GradientClrLine.AddRange(value)

            End If

            '全部重新设定以及绘制
            OnReBuildCLines()

        End Set
    End Property


    <CategoryAttribute("颜色渐变集合"), _
DisplayName("填充渐变色集合")> _
    Public Property GradientClrPolygonArrayProperty() As Drawing.Color()
        Get
            Return GetGradientClrPolygonArray()
        End Get
        Set(ByVal value As Drawing.Color())

            If value.Length > 0 Then
                GradientClrPolygon.Clear()
                GradientClrPolygon.AddRange(value)

            End If

            OnReBuildCLines()
        End Set
    End Property

    Private Function GetGradientClrPolygonArray() As Drawing.Color()

        Dim temp As Drawing.Color()
        temp = GradientClrPolygon.ToArray()
        Return temp


    End Function

    Private Sub SetGradientClrPolygonArray()

    End Sub


    Private Sub OnReBuildCLines()
        Dim hp As New CTHelperV2(Me)
        Dim dlist As New List(Of Double)
        For Each cl As ContourLine In CListProperty

            dlist.Add(cl.VProperty)
        Next

        Me.CListProperty = hp.GetResultList(dlist)

    End Sub

    Dim cList As List(Of ContourLine)
    <CategoryAttribute("等值线设置"), _
  Editor(GetType(ContourEditor), GetType(UITypeEditor)), _
 DisplayName("等值线集合编辑器")> _
  Public Property CListProperty() As List(Of ContourLine)
        Get
            Return cList
        End Get
        Set(ByVal value As List(Of ContourLine))
            cList = value

            '这里添加的代码，是为了加速等值线光滑算法----------------------------

            '取得目前等值线的数组
            Dim dblVa(CListProperty.Count - 1) As Double
            Dim tempi As Integer = 0

            For Each l As ContourLine In CListProperty

                dblVa(tempi) = l.VProperty

                tempi += 1
            Next

            '将它整个赋值给对应的处理器


            MyContours.SetContours(dblVa)
            If Me.m_bSmoothLine Then
                MyContours.Slip = True
                MyContours.SetContoursSlip()

            End If


            Me.AllRedraw()

        End Set
    End Property


    '需要指定的属性

    Dim m_LBPointXA As Double
    <CategoryAttribute("等值线设置"), _
 DisplayName("等值线X轴方向偏移值"), _
 Browsable(False)> _
   Public Property ContourPreX() As Double
        Get
            Return m_LBPointXA
        End Get
        Set(ByVal value As Double)

            m_LBPointXA = value

            Me.AllRedraw()
        End Set
    End Property
    Dim m_LBPointYA As Double
    <CategoryAttribute("特定设置"), _
DisplayName("等值线Y轴方向偏移值"), _
Browsable(False)> _
   Public Property ContourPreY() As Double
        Get
            Return m_LBPointYA
        End Get
        Set(ByVal value As Double)

            m_LBPointYA = value

            Me.AllRedraw()

        End Set
    End Property

    Dim m_ShowLegend As Boolean
    <CategoryAttribute("图例设置"), _
DisplayName("是否显示图例")> _
  Property IsShowLegend() As Boolean
        Get
            Return m_ShowLegend
        End Get
        Set(ByVal value As Boolean)

            m_ShowLegend = value
            DrawLegend(m_ShowLegend)

        End Set
    End Property


    Dim m_LengendPX As Double
    <CategoryAttribute("图例设置"), _
DisplayName("图例X方向偏移量")> _
   Property LengendPreX() As Double
        Get
            Return m_LengendPX
        End Get
        Set(ByVal value As Double)
            If m_LengendPX = value Then
            Else

                m_LengendPX = value
                DrawLegend(m_ShowLegend)
            End If

        End Set
    End Property

    Dim m_LengendPY As Double
    <CategoryAttribute("图例设置"), _
DisplayName("图例Y方向偏移量")> _
   Property LengendPreY() As Double
        Get
            Return m_LengendPY
        End Get
        Set(ByVal value As Double)
            If m_LengendPY = value Then
            Else

                m_LengendPY = value
                DrawLegend(m_ShowLegend)

            End If

        End Set
    End Property

    Dim m_bLengendFormat As Boolean
    <CategoryAttribute("图例设置"), _
DisplayName("启用图例文本格式化")> _
  Property IsLengendTextFormat() As Boolean
        Get
            Return m_bLengendFormat
        End Get
        Set(ByVal value As Boolean)
            If m_bLengendFormat = value Then
            Else

                m_bLengendFormat = value
                DrawLegend(m_ShowLegend)

            End If

        End Set
    End Property

    Dim m_LengendNumPts As UInteger
    <CategoryAttribute("图例设置"), _
DisplayName("图例文本格式化小数点位数")> _
  Property LTextFormatNum() As UInteger
        Get
            Return m_LengendNumPts


        End Get
        Set(ByVal value As UInteger)
            If m_LengendNumPts = value Then

            Else
               
                m_LengendNumPts = value
                DrawLegend(m_ShowLegend)

            End If
        End Set
    End Property


    Protected lineWidth As Double

    <CategoryAttribute("外观设置"), _
   DisplayName("线条宽度")> _
   Public Overridable Property LineWidthProperty() As Double
        Get
            Return lineWidth
        End Get
        Set(ByVal value As Double)
            lineWidth = value

            Me.OnLnWdChanged(lineWidth)

        End Set
    End Property

    Private Sub OnLnWdChanged(ByVal d As Double)

        mapwin.set_ShapeLayerLineWidth(m_iLayer, d)
    End Sub

    Dim m_DrawHandle As Integer
    '下面的函数暂时以子函数的身份，以后可能改为基类虚函数


    Public Sub DrawLegend(ByVal bl As Boolean)



        mapwin.ClearDrawing(m_DrawHandle)

        If MyContours.GridPoint IsNot Nothing AndAlso MyContours.GridPoint.Length > 0 Then

        Else
            Return

        End If

        'If Not bContourReady Then

        '    Return

        'End If

        If bl Then

            Dim xlength = MyContours.Xmax - MyContours.Xmin
            Dim yLength = MyContours.Ymax - MyContours.Ymin

            'Dim xOrg = MyContours.x0
            'Dim yOrg = MyContours.y0


            Dim pt As New MapWinGIS.Point


            '这里的contourprex只是非标准位置的偏移
            pt.x = MyContours.Xmax + Me.ContourPreX + 0.1 * xlength
            pt.y = MyContours.Ymax + Me.ContourPreY - 0.03 * yLength


            'pt.x = xOrg + Me.ContourPreX + 0.5 * xlength + 0.1 * xlength



            'pt.y = yOrg + Me.ContourPreY + 0.5 * yLength - 0.03 * yLength   'z增加0.03的纵向偏量


           






            Dim nColors As Integer = CListProperty.Count

            Dim dPart As Double = 0.94 / Double.Parse(nColors)



            '将图例的位置属性加进去
            pt.x = pt.x + m_LengendPX
            pt.y = pt.y + m_LengendPY



            ' Me.DrawRectangle(pt, 0.18 * xlength, 0.07 * yLength)

            Me.DrawRectangle(pt, 0.035 * xlength, dPart * yLength)

        End If

    End Sub

    Protected Sub DrawRectangle(ByVal Startpt As MapWinGIS.Point, ByVal w As Double, ByVal h As Double)
        Dim ucl As UInt32 = 0

        ' Dim m_DrawHandle As Integer

        m_DrawHandle = mapwin.NewDrawing(tkDrawReferenceList.dlSpatiallyReferencedList)
        Dim xps(4) As Double
        Dim yps(4) As Double

        'Dim xpsB(3) As Double
        'Dim ypsB(3) As Double



        Dim pt As MapWinGIS.Point = Startpt

        Dim tempList As New List(Of ContourLine)
        tempList.AddRange(CListProperty)
        tempList.Reverse()

        For Each cl As ContourLine In tempList

            ucl = RGB(cl.ClrProperty.R, cl.ClrProperty.G, cl.ClrProperty.B)

            '我就以顺时针为标准吧

            xps(0) = pt.x
            yps(0) = pt.y
            xps(1) = pt.x + w
            yps(1) = pt.y
            xps(2) = pt.x + w
            yps(2) = pt.y - h
            xps(3) = pt.x
            yps(3) = pt.y - h

            '这个店是为了使线闭合
            xps(4) = pt.x
            yps(4) = pt.y


            'xpsB(0) = pt.x - 5
            'ypsB(0) = pt.y
            'xpsB(1) = pt.x + w
            'ypsB(1) = pt.y
            'xpsB(2) = pt.x + w
            'ypsB(2) = pt.y - h
            'xpsB(3) = pt.x
            'ypsB(3) = pt.y - h


            pt.x = xps(3)
            pt.y = yps(3)


            mapwin.DrawPolygon(xps, yps, 5, ucl, True)
            mapwin.DrawWidePolygon(xps, yps, 5, 0, False, 1)



            'cl.VProperty.ToString("{0:3}")
            ' Dim str As String = String.Format(cl.VProperty.ToString(), )

            If m_bLengendFormat Then

                Dim strFor As String = "f" + m_LengendNumPts.ToString()


                mapwin.AddDrawingLabel(m_DrawHandle, cl.VProperty.ToString(strFor), 0, xps(1) + w / 2, yps(2) + 3 * Me.xScale * Me.m_TextFont.Size, tkHJustification.hjRight)
            Else
                mapwin.AddDrawingLabel(m_DrawHandle, cl.VProperty.ToString(), 0, xps(1) + w / 2, yps(2) + 3 * Me.xScale * Me.m_TextFont.Size, tkHJustification.hjRight)



            End If





        Next






    End Sub











    '真正直接调用的是drawall,注意

    Protected Overrides Sub DrawMySelf()

        DrawLegend(m_ShowLegend)

        'If bContourReady Then

        If MyContours.GridPoint IsNot Nothing AndAlso MyContours.GridPoint.Length > 0 Then

            DrawContourLines(cList)

        End If



        'End If




    End Sub



    ' Private m_ShowContourText As Boolean = True

    ' <CategoryAttribute("等值线标注"), _
    'DisplayName("标注是否显示")> _
    ' Public Property ShowContourText() As Boolean
    '     Get
    '         Return m_ShowContourText
    '     End Get
    '     Set(ByVal value As Boolean)
    '         If m_ShowContourText <> value Then
    '             m_ShowContourText = value
    '             Me.DrawText()
    '         End If

    '     End Set
    ' End Property

    Protected Overrides Sub DrawText()

        mapwin.ClearLabels(m_iLayer)

        mapwin.LayerFont(m_iLayer, m_TextFont.Name, m_TextFont.Size)

      

        If Not m_bShowText Then
            Return
        End If


        If m_lstColor.Count > 0 Then

            lstLineTextCahe.Clear()
            For Each myc As ContourLine In m_lstColor

                Me.DrawContourLineText(myc.VProperty)

            Next



        End If



        ''当等值线有值时
        'If m_lstColor.Count > 0 Then


        '    '查看是否有对应的正确的缓存
        '    If Not bLineTextCacheReady Then

        '        '当没有对应的正确缓存时，第一步是清空旧有的缓存
        '        lstLineTextCahe.Clear()

        '        For Each myc As ContourLine In m_lstColor

        '            Me.DrawContourLineText(myc.VProperty)

        '        Next


        '        '下面的缓存算法，还有一定的问题，所以暂时不启用
        '        bLineTextCacheReady = False

        '    Else

        '        '拥有对应的正确的缓存的话
        '        Me.OnMoveDrawContourLineText()



        '    End If





        'End If

    End Sub


    Public Overrides Sub OnExtentsChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim p1 As New MapWinGIS.Point
        Dim p2 As New MapWinGIS.Point

        mapwin.PixelToProj(0, 0, p1.x, p1.y)
        mapwin.PixelToProj(1, 1, p2.x, p2.y)

        xScale = p2.x - p1.x

        Me.DrawLegend(m_ShowLegend)

        Me.DrawText()


    End Sub


    '内部功能函数
    '排序用的比较函数
    Private Shared Function compareContour(ByVal x As ContourLine, ByVal y As ContourLine) As Integer
        If x Is Nothing Then
            If y Is Nothing Then
                ' If x is Nothing and y is Nothing, they're
                ' equal. 
                Return 0
            Else
                ' If x is Nothing and y is not Nothing, y
                ' is greater. 
                Return -1
            End If
        Else



            If y Is Nothing Then
                ' ...and y is Nothing, x is greater.
                Return 1
            Else
                ' ...and y is not Nothing, compare the 
                ' lengths of the two strings.
                '
                Dim retval As Integer = _
                    x.VProperty.CompareTo(y.VProperty)

                If retval <> 0 Then
                    ' If the strings are not of equal length,
                    ' the longer string is greater.
                    '
                    Return retval
                Else
                    ' If the strings are of equal length,
                    ' sort them with ordinary string comparison.
                    '
                    'Return x.CompareTo(y)

                    Return 0
                End If
            End If


        End If


    End Function
    Protected Sub DrawContourLines(ByVal lt As List(Of ContourLine))

        '判断是否为空
        If lt Is Nothing Then
            Return
        End If

        If lt.Count = 0 Then
            Return
        End If

        '首先要对集合排序，去重
        lt.Sort(AddressOf compareContour)
        Dim ltTemp As New List(Of ContourLine)
        For Each l As ContourLine In lt
            If Not ltTemp.Contains(l) Then
                ltTemp.Add(l)
            End If
        Next



        '清空上一次的绘制记录,前面的函数中已经完成了此功能






        ' MyContours.SetContoursSlip()
        'MyContours.Slip = True







        Dim shps As New Dictionary(Of Double, MapWinGIS.Shape())
        '取得原始的浓度大小,以及那个完成自我挖空的过程
        Dim sl As List(Of Shape)

        For Each myc As ContourLine In ltTemp

            sl = Me.GetOriginPolygonShapes(myc.VProperty)

            If sl IsNot Nothing Then



                Dim myshapes(sl.Count - 1) As MapWinGIS.Shape

                For w As Integer = 0 To sl.Count - 1

                    myshapes(w) = sl.Item(w)

                Next




                shps.Add(myc.VProperty, myshapes)

            Else

                Dim myshapes(-1) As MapWinGIS.Shape

                shps.Add(myc.VProperty, myshapes)



            End If

        Next

        Dim holeShapes As New Dictionary(Of Double, MapWinGIS.Shape())

        '开始与别的形状比较
        For j As Integer = ltTemp.Count - 1 To 0 Step -1
            If j = (ltTemp.Count - 1) Then

                If shps.ContainsKey(ltTemp.Item(j).VProperty) Then

                    Dim atShapes() As MapWinGIS.Shape = shps.Item(ltTemp.Item(j).VProperty)

                    holeShapes.Add(ltTemp.Item(j).VProperty, atShapes)



                End If


            Else

                '当前浓度shape,与前一浓度shape
                Dim nShapes() As MapWinGIS.Shape = shps.Item(ltTemp.Item(j).VProperty)
                Dim pShapes() As MapWinGIS.Shape = shps.Item(ltTemp.Item(j + 1).VProperty)

                '转化后的shape
                Dim AfterTranShapes(nShapes.Length - 1) As MapWinGIS.Shape

                Dim u As New MapWinGIS.Utils

                For m As Integer = 0 To nShapes.Length - 1

                    Dim sp As New MapWinGIS.Shape
                    sp = nShapes(m)

                    For n As Integer = 0 To pShapes.Length - 1

                        sp = u.ClipPolygon(PolygonOperation.DIFFERENCE_OPERATION, sp, pShapes(n))

                    Next


                    AfterTranShapes(m) = sp


                Next

               



                holeShapes.Add(ltTemp.Item(j).VProperty, AfterTranShapes)




            End If



        Next



        '这里以上的代码是可以进行分开操作的 ，经理想要后台处理，那么这里就需要一个全局变量，来保存生成的结果，但是里面的掺杂代码比较多


        '开始按照顺序绘制
        Dim k As Double
        Dim v As MapWinGIS.Shape()


        Dim sfPoly As Shapefile = mapwin.get_GetObject(m_iLayer)
        sfPoly.StartEditingShapes(True)
        For Each l As ContourLine In ltTemp
            k = l.VProperty
            v = holeShapes.Item(l.VProperty)
            For q As Integer = 0 To v.Length - 1

                Me.AddLayerShapePolygon("contour", v(q), k.ToString())

            Next


        Next
        sfPoly.StopEditingShapes()


        m_lstColor.Clear()
        m_lstColor.AddRange(ltTemp)


        For Each myc As ContourLine In ltTemp

            Me.ColorContour(myc.VProperty.ToString(), myc.ClrProperty, myc.LnColorProperty, myc.BShowPolyProperty)
        Next


    End Sub

    '这个用来优化已经存在的打开和保存，重画颜色，而不重画形状
    Private m_lstColor As New List(Of ContourLine)
    Protected Sub ReColorAllContour()

        If m_lstColor.Count > 0 Then

            For Each myc As ContourLine In m_lstColor

                Me.ColorContour(myc.VProperty.ToString(), myc.ClrProperty, myc.LnColorProperty, myc.BShowPolyProperty)
            Next

        End If

     

    End Sub


    Protected Function GetOriginPolygonShapes(ByVal dv As Double) As List(Of MapWinGIS.Shape)

        Dim shps As New List(Of MapWinGIS.Shape)


        If MyContours Is Nothing Then
            Return Nothing
        End If

      
        '-----------------------------------------------------

        Dim ArrayContourLines(-1) As DrawContour.ContourPoints
        ArrayContourLines = MyContours.GetContourLines(dv)


        'Dim temp(25, 25) As Double
        'temp = MyContours.GridPoint
        'Dim bf As New BinaryFormatter
        'Dim stream As Stream = New FileStream("c:\test\gridpoint", FileMode.OpenOrCreate, FileAccess.Write)

        'bf.Serialize(stream, temp)



        If ArrayContourLines.Length <= 0 Then
            Return Nothing
        End If

        '原来得到是相对坐标，这下玩大了，还得改成绝对坐标







        Dim ClipPoints As New List(Of MapWinGIS.Point())

        '首先循环一次，取出所有的内向型等值线
        For Each pts As DrawContour.ContourPoints In ArrayContourLines

            If pts.Great = 1 Then

                Dim n As Integer = pts.vecContourPoints.Length


                Dim ptlist(n) As MapWinGIS.Point
                Dim i As Integer = 0
                For Each spts As DrawContour.Point3D In pts.vecContourPoints
                    Dim p As New MapWinGIS.Point
                    p.x = spts.x
                    p.y = spts.y

                    '转换绝对坐标
                    p.x = p.x + Me.ContourPreX
                    p.y = p.y + Me.ContourPreY


                    ptlist(i) = p

                    i = i + 1


                Next


                ClipPoints.Add(ptlist)




            End If

        Next


        For Each pts As DrawContour.ContourPoints In ArrayContourLines

            Dim n As Integer = pts.vecContourPoints.Length


            Dim ptlist(n) As MapWinGIS.Point
            Dim i As Integer = 0
            For Each spts As DrawContour.Point3D In pts.vecContourPoints
                Dim p As New MapWinGIS.Point
                p.x = spts.x
                p.y = spts.y


                '转换绝对坐标
                p.x = p.x + Me.ContourPreX
                p.y = p.y + Me.ContourPreY


                ptlist(i) = p

                i = i + 1


            Next


            'great 0 正常绘制

            If pts.Great = 0 Then
                ' myLayers.AddLayerShapePolygon("contour", ptlist, dv.ToString(), prop.BSelfDefProperty, prop.LineColorProperty, preName, ClipPoints)

                Dim shp As Shape = Me.GetShapePolygonWithoutHole(ptlist, ClipPoints)

                shps.Add(shp)





            End If




        Next


        Return shps



    End Function

    Protected Function GetShapePolygonWithoutHole(ByVal ptlist() As MapWinGIS.Point, ByVal ClipList As List(Of MapWinGIS.Point())) As Shape

        '外边点的添加，使封闭
        Dim nl As Integer = ptlist.Length



        ReDim Preserve ptlist(nl + 1)

        ptlist(nl) = ptlist(0)




        Dim shp As New Shape
        shp.ShapeType = ShpfileType.SHP_POLYGON
        Dim ptIndex As Integer = 0

        Dim n As Integer = ptlist.Length



        For i As Integer = 1 To n

            shp.InsertPoint(ptlist(i - 1), ptIndex)


        Next


        Dim mshp As MapWinGIS.Shape = shp

        '本浓度剔除
        If ClipList.Count > 0 Then

            ptIndex = 0

            Dim u As New MapWinGIS.Utils
            For Each cpoints As MapWinGIS.Point() In ClipList

                If (u.PointInPolygon(mshp, cpoints(0))) Then
                    Dim clipShp As New Shape
                    clipShp.ShapeType = ShpfileType.SHP_POLYGON

                    Dim k As Integer = cpoints.Length

                    For i As Integer = 1 To k

                        clipShp.InsertPoint(cpoints(i - 1), ptIndex)


                    Next

                    '加入第一个点的情况

                    clipShp.InsertPoint(cpoints(0), ptIndex)



                    mshp = u.ClipPolygon(MapWinGIS.PolygonOperation.DIFFERENCE_OPERATION, mshp, clipShp)

                End If

            Next

        End If



        Return mshp



    End Function

    Protected Sub AddLayerShapePolygon(ByVal name As String, ByVal mshp As MapWinGIS.Shape, ByVal sname As String)

        



        Dim sfPoly As Shapefile = mapwin.get_GetObject(m_iLayer)
        Dim shpIndex As Integer = sfPoly.NumShapes

        sfPoly.EditInsertShape(mshp, shpIndex)

        sfPoly.EditCellValue(0, shpIndex, sname)




        mapwin.Redraw()

    End Sub

    Protected Sub ColorContour(ByVal sn As String, ByVal clr As Drawing.Color, ByVal clrLine As Drawing.Color, ByVal bV As Boolean)




        '这里指的是填充颜色,下边指的是线条颜色

        Dim ucl As UInt32 = RGB(clr.R, clr.G, clr.B)

        Dim uclLine As UInt32 = RGB(clrLine.R, clrLine.G, clrLine.B)



        Dim mlist As List(Of Integer)

        mlist = Me.GetAsistLayerShapeGroup(sn)



        For Each i As Integer In mlist

            ' mapMain.set_ShapeFillColor(iLayer, i, True)
            ' mapMain.set_ShapeFillTransparency(iLayer, i, 1)
            mapwin.set_ShapeFillColor(m_iLayer, i, ucl)
            mapwin.set_ShapeLineColor(m_iLayer, i, uclLine)

            mapwin.set_ShapeVisible(m_iLayer, i, bV)


        Next




    End Sub

    Protected Function GetAsistLayerShapeGroup(ByVal sname As String) As List(Of Integer)

        Dim mList As New List(Of Integer)


        Dim sfData As Shapefile = mapwin.get_GetObject(m_iLayer)
        If sfData Is Nothing Then
            Return mList
        End If
        Dim n As Integer = sfData.NumShapes
        For i As Integer = 0 To n - 1

            If (sfData.CellValue(0, i).ToString() = sname) Then
                mList.Add(i)
            End If

        Next


        Return mList


    End Function

    Public Overrides Sub InitNewLayer(ByRef m As AxMapWinGIS.AxMap, ByVal OutPath As String)


        Dim sf As New Shapefile
        Dim strPath(2) As String


        'strPath(0) = "C:\temp\" + lname + ".shp"
        'strPath(1) = "C:\temp\" + lname + ".dbf"
        'strPath(2) = "C:\temp\" + lname + ".shx"

        'If System.IO.File.Exists(strPath(0)) Then
        '    System.IO.File.Delete(strPath(0))
        '    System.IO.File.Delete(strPath(1))
        '    System.IO.File.Delete(strPath(2))

        'End If

        sf.CreateNew("", MapWinGIS.ShpfileType.SHP_POLYGON)




        Dim f As New Field

        f = New Field
        f.Name = "Name"
        f.Type = FieldType.STRING_FIELD
        f.Width = 50

        sf.StartEditingShapes(True)
        sf.EditInsertField(f, 0)
        sf.StopEditingShapes(True, True)


        '加入载入的逻辑

        Dim strSave As String = OutPath + lname + ".shp"

        strPath(0) = OutPath + lname + ".shp"
        strPath(1) = OutPath + lname + ".dbf"
        strPath(2) = OutPath + lname + ".shx"
        For i As Integer = 0 To strPath.Length - 1
            If System.IO.File.Exists(strPath(i)) Then
                Try
                    System.IO.File.SetAttributes(strPath(i), IO.FileAttributes.Normal)
                    System.IO.File.Delete(strPath(i))
                Catch ex As Exception

                End Try

            End If
        Next

        Dim bS As Boolean = sf.SaveAs(strSave)

        If Not bS Then
            System.Windows.Forms.MessageBox.Show(lname + "文件创建失败！，请查看电脑软件使用权限")

        End If

        fname = strSave

        Me.InitLayer(m)
    End Sub

    Public Overrides Sub InitProp()

        Me.OnLnWdChanged(lineWidth)

        Me.ReColorAllContour()

        Me.DrawLegend(m_ShowLegend)



    End Sub


    Dim m_LabelFts As UInteger = 3
    <CategoryAttribute("等值线标注"), _
DisplayName("等值线标注格式化小数点位数")> _
  Property CLTextFormatNum() As UInteger
        Get
            Return m_LabelFts


        End Get
        Set(ByVal value As UInteger)
            If m_LabelFts = value Then

            Else

                m_LabelFts = value
                Me.DrawText()
            End If
        End Set
    End Property

    '下面这个属性用来控制等值线点边数,
    Dim m_ptsPerlbl As Integer = 10
    <CategoryAttribute("等值线标注"), _
   DisplayName("等值线标注采样点数")> _
    Public Property m_PtsPerLabel() As Integer
        Get
            Return m_ptsPerlbl
        End Get
        Set(ByVal value As Integer)

            If m_ptsPerlbl = value Then

            Else
                If value < 3 Then
                    value = 3
                End If

                m_ptsPerlbl = value
                Me.DrawText()

            End If

        End Set
    End Property

    Dim m_LableOnLine As Boolean = True
    <CategoryAttribute("等值线标注"), _
 DisplayName("标注位置是否在线上")> _
  Public Property LableOnLine() As Boolean
        Get
            Return m_LableOnLine
        End Get
        Set(ByVal value As Boolean)
            If m_LableOnLine = value Then
            Else
                m_LableOnLine = value
                Me.DrawText()

            End If

        End Set
    End Property


    '为了提高运算效率，需要对下面的位置值缓存,对于何时清空缓存，我们还要好好想想
    Dim bLineTextCacheReady As Boolean = False  '这个值为false时，需要更新显示文本，即清空缓存，从新计算

    Dim lstLineTextCahe As New List(Of LineTextCache)


    ''' <summary>
    ''' 当存在对应的缓存时，用此函数进行绘制
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub OnMoveDrawContourLineText()
        For Each ltc As LineTextCache In lstLineTextCahe



            Dim r As Double = ltc.r


            '下面这段代码，是为了确保等值线的标注，在线上
            If m_LableOnLine Then


                If r <> -1 Then

                    '将等值线，写到线上面的算法
                    Dim anglePi As Double = r * Math.PI / 180
                    Dim len As Double = Me.xScale * Me.m_TextFont.Size



                    ltc.posx = ltc.posx - Math.Sin(anglePi) * len
                    ltc.posy = ltc.posy + Math.Cos(anglePi) * len



                End If



            End If



            '下面进行对应的缓存绘制，希望借此提高效率

            mapwin.AddLabelEx(m_iLayer, ltc.dv.ToString(ltc.strFormat), ltc.uclr, ltc.posx, ltc.posy, tkHJustification.hjRaw, r)


        Next


    End Sub


    Public Sub DrawContourLineText(ByVal dv As Double)

        If m_ptsPerlbl < 3 Then
            m_ptsPerlbl = 3
        End If


        Dim shps As New List(Of MapWinGIS.Shape)


        If MyContours Is Nothing Then
            Return
        End If

        Dim ArrayContourLines(-1) As DrawContour.ContourPoints
        ArrayContourLines = MyContours.GetContourLines(dv)


        If ArrayContourLines Is Nothing Then
            Return
        End If


        If ArrayContourLines.Length <= 0 Then
            Return
        End If

        '原来得到是相对坐标，这下玩大了，还得改成绝对坐标







        For Each pts As DrawContour.ContourPoints In ArrayContourLines

            Dim n As Integer = pts.vecContourPoints.Length


            Dim ptlist(n) As MapWinGIS.Point
            Dim i As Integer = 0
            For Each spts As DrawContour.Point3D In pts.vecContourPoints
                Dim p As New MapWinGIS.Point
                p.x = spts.x
                p.y = spts.y


                '转换绝对坐标
                p.x = p.x + Me.ContourPreX
                p.y = p.y + Me.ContourPreY


                ptlist(i) = p

                i = i + 1


            Next


            'great 0 正常绘制

            If pts.Great = 0 Then

                Dim length As Integer = pts.vecContourPoints.Length

                '测试个点数量，以确定是否绘制
                If pts.vecContourPoints.Length < m_ptsPerlbl Then

                    Continue For


                End If


                '每多少个边绘制一个值,变量必须大于2,因为即使只有一条线条，也要大于2个点



                Dim p1, p2 As New MapWinGIS.Point
                Dim s As Integer = length / m_ptsPerlbl

                '到达这里时，已经保证了，当小于6个点时，不经过这里，所以s 是肯定大于1 的

                For j As Integer = 0 To s - 1

                    'p1.x = pts.vecContourPoints(j * m_ptsPerlbl).x
                    'p1.y = pts.vecContourPoints(j * m_ptsPerlbl).y

                    'p2.x = pts.vecContourPoints(j * m_ptsPerlbl + 1).x
                    'p2.y = pts.vecContourPoints(j * m_ptsPerlbl + 1).y


                    '实行尾部算法

                    p1.x = pts.vecContourPoints(j * m_ptsPerlbl + m_ptsPerlbl / 2 - 1).x
                    p1.y = pts.vecContourPoints(j * m_ptsPerlbl + m_ptsPerlbl / 2 - 1).y

                    p2.x = pts.vecContourPoints(j * m_ptsPerlbl + m_ptsPerlbl / 2).x
                    p2.y = pts.vecContourPoints(j * m_ptsPerlbl + m_ptsPerlbl / 2).y



                    '首先保证点是从左往右的

                    Dim r As Double
                    If p1.x > p2.x Then
                        r = Me.GetAngleFromTwoPoint(p1, p2)
                    Else

                        r = Me.GetAngleFromTwoPoint(p2, p1)

                    End If

                    Dim pos As New MapWinGIS.Point

                    pos.x = (p1.x + p2.x) / 2
                    pos.y = (p1.y + p2.y) / 2


                    '确定值不在边界上
                    'If pos.x >= MyContours.Xmax Or pos.x <= MyContours.Xmin Or pos.y >= MyContours.Ymax Or pos.y <= MyContours.Ymin Then

                    '    Continue For


                    'End If


                    '这里是为了缓存的需要所填写的代码，是在没有对应的缩放前的原始数据
                    Dim ptempx, ptempy As Double
                    ptempx = pos.x
                    ptempy = pos.y




                    If m_LableOnLine Then


                        If r <> -1 Then

                            '将等值线，写到线上面的算法
                            Dim anglePi As Double = r * Math.PI / 180
                            Dim len As Double = Me.xScale * Me.m_TextFont.Size



                            pos.x = pos.x - Math.Sin(anglePi) * len
                            pos.y = pos.y + Math.Cos(anglePi) * len



                        End If



                    End If






                    Dim str As String = "f" + m_LabelFts.ToString


                    Dim uclr As UInt32 = RGB(m_TextColor.R, m_TextColor.G, m_TextColor.B)


                    '避免一些极其特殊的值
                    If r <> -1 Then

                        mapwin.AddLabelEx(m_iLayer, dv.ToString(str), uclr, pos.x, pos.y, tkHJustification.hjRaw, r)


                        '建立缓存信息



                        Dim ltc As New LineTextCache(dv, str, uclr, ptempx, ptempy, r)

                        lstLineTextCahe.Add(ltc)



                    End If



                Next











            End If




        Next


        Return

    End Sub

    Public Function GetAngleFromTwoPoint(ByVal p1 As MapWinGIS.Point, ByVal p2 As MapWinGIS.Point) As Double
        If p1.x = p2.x And p1.y = p2.y Then

            Return -1
        End If

        If p1.x = p2.x Then

            Return 0
        End If

        If p1.y = p2.y Then

            Return -1
        End If

        Dim k As Double = (p2.y - p1.y) / (p2.x - p1.x)

        Dim a As Double = Math.Atan(k)

        Return a * 180.0F / Math.PI


    End Function





    ''' <summary>
    ''' 是否启用光滑的曲线
    ''' </summary>
    ''' <remarks></remarks>
    Dim m_bSmoothLine As Boolean = False
    <CategoryAttribute("等值线设置"), _
    Browsable(True), _
    Description("启用后等值线会插值，可能使显示速度变慢"), _
DisplayName("是否启用等值线光滑算法")> _
  Property IsSmoothLine() As Boolean
        Get
            Return m_bSmoothLine
        End Get
        Set(ByVal value As Boolean)
            If m_bSmoothLine = value Then
            Else

                m_bSmoothLine = value
                Me.OnSetSmoothLine()

            End If

        End Set
    End Property


    ''' <summary>
    ''' 目前此函数尚未准确的完成。
    ''' </summary>
    ''' <remarks></remarks>
    Protected Sub OnSetSmoothLine()
        '前面需要更新一下drawcontour

        MyContours.Slip = m_bSmoothLine

        If MyContours.Slip Then
            MyContours.SetContoursSlip()

        End If

        Me.AllRedraw()

    End Sub


 

End Class

''' <summary>
''' 这个类用于标注缓存信息
''' </summary>
''' <remarks></remarks>
<Serializable()> Public Class LineTextCache

    Public dv As Double
    Public strFormat As String '格式化字符串
    Public uclr As UInt32  '颜色
    Public posx, posy As Double

    Public r As Double '切换角度

    Public Sub New(ByVal dv As Double, ByVal strf As String, ByVal uclr As UInt32, ByVal posx As Double, ByVal posy As Double, ByVal r As Double)

        Me.dv = dv
        Me.strFormat = strf
        Me.uclr = uclr
        Me.posx = posx
        Me.posy = posy

        Me.r = r





    End Sub





  



End Class